﻿using ApplicationBase.Core.Security;
using Infrastructure.Core.Web.Controller;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Text;
using System.Text.Json.Serialization;

namespace ApplicationBase.Core.Web.Extensions
{
    public static class ServiceCollectionExtensions
    {
        public static void AddDefaultControllers(this IServiceCollection service)
        {
            service.AddControllers()
                .AddControllersAsServices() 
                .AddNewtonsoftJson(options =>
                {
                    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //解决Json序列化循环调用
                    options.SerializerSettings.Converters.Add(new StringEnumConverter()); 
                })
                .AddJsonOptions(options =>
                {
                    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
                });
            service.Replace(ServiceDescriptor.Transient<IControllerActivator, BaseControllerActivator>());
        }

        public static void AddDefaultSwagger(this IServiceCollection service)
        {
            service.AddEndpointsApiExplorer();
            service.AddSwaggerGen(it =>
            {
                var schema = new OpenApiSecurityScheme
                {
                    Description = "Authorization header.",
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Authorization"
                    },
                    Scheme = "oauth2",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey
                };
                it.AddSecurityDefinition("Authorization", schema);

                var requirement = new OpenApiSecurityRequirement();
                requirement[schema] = new List<string>();
                it.AddSecurityRequirement(requirement);
            });
        }

        public static void AddDefaultJWT(this IServiceCollection service, IConfiguration configuration)
        {
            service.Configure<JWTOptions>(configuration.GetSection("JWT"));
            service.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(it =>
                {
                    var option = configuration.GetSection("JWT").Get<JWTOptions>();
                    byte[] bytes = Encoding.UTF8.GetBytes(option!.SigningKey);
                    var key = new SymmetricSecurityKey(bytes);
                    it.TokenValidationParameters = new()
                    {
                        ValidateIssuer = false,
                        ValidateAudience = false,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = key
                    };
                });
        }
    }
}
